package com.rlz.framemm.util;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.HandlerThread;

import com.rlz.base.util.ThreadUtil;
import com.rlz.libs.log.P;

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;

import static com.rlz.framemm.util.GifPlayer.PlayState.PLAYING;

public class GifPlayer implements LifecycleObserver {

    public static final String T = "GifPlayer";

    private final Context mContext;

    private Bitmap mBitmap;

    private OnGifListener mOnGifListener;

    private HandlerThread mHandlerThread;

    private Handler mHandler;

    private int mPlayState;

    private long mGifPlayerPtr;

    public interface PlayState {

        int IDLE = 1;

        int PREPARE = 2;

        int PLAYING = 3;

        int STOP = 4;
    }

    public interface OnGifListener {
        void start();

        void draw(Bitmap bitmap);

        void end();
    }

    static {
        System.loadLibrary("gifplayer");
    }

    public GifPlayer(Context context) {
        mContext = context;
        mGifPlayerPtr = create();
        mPlayState = PlayState.IDLE;
        mHandlerThread = new HandlerThread("GifPlayer");
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper());
        bindLifecycle();
    }

    public void setOnGifListener(OnGifListener onGifListener) {
        this.mOnGifListener = onGifListener;
    }

    public boolean assetPlay(Context context, String gifPath) {
        return play(false, context, gifPath);
    }

    public boolean storagePlay(String gifPath) {
        return play(false, null, gifPath);
    }

    public boolean assetPlay(boolean once, Context context, String gifPath) {
        return play(once, context, gifPath);
    }

    public boolean storagePlay(boolean once, String gifPath) {
        return play(once, null, gifPath);
    }


    private boolean play(final boolean once, final Context context, final String gifPath) {
        if (mPlayState == PlayState.IDLE) {
            mPlayState = PlayState.PREPARE;
            mHandler.post(() -> {
                if (mOnGifListener != null) {
                    mOnGifListener.start();
                }
                if (load(mGifPlayerPtr, context != null ? context.getResources().getAssets() : null, gifPath)) {
                    mPlayState = PLAYING;
                    mBitmap = Bitmap.createBitmap(getWidth(mGifPlayerPtr),
                            getHeight(mGifPlayerPtr), Bitmap.Config.ARGB_8888);
                    start(mGifPlayerPtr, once, mBitmap, () -> {
                        if (mOnGifListener != null) {
                            ThreadUtil.runOnUiThread(() -> {
                                mOnGifListener.draw(mBitmap);
                            });
                        }
                    });
                }
                mPlayState = PlayState.IDLE;
                if (mOnGifListener != null) {
                    mOnGifListener.end();
                }
            });
        } else {
            return false;
        }
        return true;
    }

    public boolean pause() {
        if (mPlayState == PLAYING) {
            pause(mGifPlayerPtr);
            return true;
        }
        return false;
    }

    public boolean resume() {
        if (mPlayState == PLAYING) {
            resume(mGifPlayerPtr);
            return true;
        }
        return false;
    }

    public boolean stop() {
        if (mPlayState != PlayState.IDLE) {
            mPlayState = PlayState.STOP;
            stop(mGifPlayerPtr);
            mHandler.post(() -> mPlayState = PlayState.IDLE);
            return true;
        }
        return false;
    }

    public void destroy() {
        stop(mGifPlayerPtr);
        mHandler.post(() -> {
            release(mGifPlayerPtr);
            mGifPlayerPtr = 0;
            mBitmap = null;
            mHandler = null;
            mHandlerThread.quit();
            mHandlerThread = null;
        });

        unBindLifecycle();
    }

    public boolean isPlayer(){
        return mPlayState == PLAYING;
    }

    private void bindLifecycle() {
        if (mContext instanceof LifecycleOwner) {
            LifecycleOwner lifecycleOwner = (LifecycleOwner) mContext;
            lifecycleOwner.getLifecycle().addObserver(this);
        }
    }

    private void unBindLifecycle() {
        if (mContext instanceof LifecycleOwner) {
            LifecycleOwner lifecycleOwner = (LifecycleOwner) mContext;
            lifecycleOwner.getLifecycle().removeObserver(this);
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    private void onPause() {
        pause();
        P.d(T,"onPause");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    private void onResume() {
        resume();
        P.d(T,"onResume");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    private void onDestroy() {
        destroy();
        P.d(T,"onDestroy");
    }


    private native long create();

    private native boolean load(long ptr, AssetManager assetManager, String gifPath);

    private native void start(long ptr, boolean once, Bitmap bitmap, Runnable updateBitmap);

    private native int getWidth(long ptr);

    private native int getHeight(long ptr);

    private native void pause(long ptr);

    private native void resume(long ptr);

    private native void stop(long ptr);

    private native void release(long ptr);


}
